/**
 * 文件上传下载管理业务逻辑类
 */
package net.sapfree.fileUpload;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import net.sapfree.common.Constants;
import net.sapfree.core.util.UUIDGenerator;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.log4j.Logger;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;



/**
 * @author Administrator
 * 
 */
public class FileUploadManagerHandler
{
    /**
     * 日志记录
     */
    private static Logger log =
        Logger.getLogger(FileUploadManagerServlet.class);
    
    
    
    /**
     * 保存客户端上传过来的文件到本地目录,返回文件名和相对路径
     * 
     * @throws IOException
     * @throws FileUploadException
     */
    public Map<String, String[]> saveFile(HttpServletRequest request)
    {
        return saveFile(request, "");
    }
    
    /**
     * 保存客户端上传过来的文件到本地目录,返回文件名和相对路径
     * 
     * @param strUUID 文档上传的默认文件名 UUID
     * @throws IOException
     * @throws FileUploadException
     */
    public Map<String, String[]> saveFile(HttpServletRequest request,
        String strUUID)
    {
        Map<String, String[]> kv = new HashMap<String, String[]>();
        String realpath = Constants.FILE_UPLOAD_PATH;
        
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String tmpDir = realpath + File.separator + "temp" + File.separator+ df.format(new Date()) + File.separator; // 临时目录
        // 判断临时目录是否存在
        File tmpPath_file = new File(tmpDir);
        if (!tmpPath_file.exists() || !tmpPath_file.isDirectory())
        {
            if (!tmpPath_file.mkdirs())
            {
                log.debug("创建不存在的文件夹：" + tmpDir);
                return kv;
            }
        }
        // 文件保存路径：以日期为文件夹
        String savePath = df.format(new Date());
        // 判断upload目录是否存在
        File filepath = new File(realpath + File.separator + savePath);
        if (!filepath.exists() || !filepath.isDirectory())
        {
            if (!filepath.mkdirs())
            {
                log.debug("创建不存在的文件夹：" + realpath + File.separator + savePath);
                return kv;
            }
            
        }
        if (ServletFileUpload.isMultipartContent(request))
        {
            // 创建该对象
            DiskFileItemFactory dff = new DiskFileItemFactory();
            // 指定上传文件的临时目录
            dff.setRepository(tmpPath_file);
            // 指定在内存中缓存数据大小,单位为byte
            dff.setSizeThreshold(Constants.TMP_FILE_SIZE);
            // 创建该对象
            ServletFileUpload sfu = new ServletFileUpload(dff);
            // 指定单个上传文件的最大值
            sfu.setSizeMax(Constants.FILE_MAX_SIZE);
            
            FileItemIterator fii;
            BufferedInputStream in = null;
            BufferedOutputStream out = null;
            try
            {
                fii = sfu.getItemIterator(request);
                // 解析request
                // 请求,并返回FileItemIterator集合
                while (fii.hasNext())
                {
                    // 从集合中获得一个文件流
                    FileItemStream fis = fii.next();
                    // 过滤掉表单中非文件域
                    if (!fis.isFormField() && fis.getName().length() > 0)
                    {
                        // 文件名为uuid
                        String uuid = strUUID;
                        if (null == uuid || "".equals(uuid))
                        {
                            uuid = UUIDGenerator.getUUID();
                        }
                        String strFileName = fis.getName();
                        String strExt =
                            strFileName.substring(strFileName.lastIndexOf("."));
                        String fileName = uuid + strExt.toLowerCase();
                        // 获得文件输入流
                        in = new BufferedInputStream(fis.openStream());
                        // 获得文件输出流
                        out =
                            new BufferedOutputStream(new FileOutputStream(
                                new File(realpath + File.separator + savePath
                                    + File.separator + fileName)));
                        // 开始把文件写到你指定的上传文件夹
                        Streams.copy(in, out, true);
                        String[] strArr = new String[2];
                        strArr[0] = savePath + "/" + fileName;
                        strArr[1] = fis.getName().substring(fis.getName().lastIndexOf("\\") + 1);
                        kv.put(uuid, strArr);
                        in.close();
                        out.close();
                    }
                }
            }
            catch (FileUploadException e)
            {
                log.error("文件上传失败 FileUploadException:", e);
            }
            catch (IOException e)
            {
                log.error("文件上传IOException:", e);
            }
            finally
            {
                if (null != in)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException e)
                    {
                        log.error("文件上传IOException:", e);
                    }
                }
                if (null != out)
                {
                    try
                    {
                        out.close();
                    }
                    catch (IOException e)
                    {
                        log.error("文件上传IOException:", e);
                    }
                }
            }
        }
        return kv;
    }
    
    
    
    /**
     * 保存客户端上传过来的文件到本地目录,返回文件名和相对路径
     * 
     * @throws IOException
     * @throws FileUploadException
     */
    public String[] savePhoto(HttpServletRequest request)
    {
        return savePhoto(request, "");
    }
    
    /**
     * 保存客户端上传过来的照片到本地目录,返回原文件名和相对路径
     * 
     * @param strUUID 文档上传的默认文件名 UUID
     * @throws IOException
     * @throws FileUploadException
     */
    public String[] savePhoto(HttpServletRequest request,String imageUuid)
    {
    	String[] strArr = new String[3];
        Map<String, String> kv = new HashMap<String, String>();
        String realpath = Constants.PHOTO_UPLOAD_PATH;
        
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        
        String tmpDir = realpath + File.separator + "temp" + File.separator+ df.format(new Date()) + File.separator; // 临时目录
        // 判断临时目录是否存在
        File tmpPath_file = new File(tmpDir);
        if (!tmpPath_file.exists() || !tmpPath_file.isDirectory())
        {
            if (!tmpPath_file.mkdirs())
            {
                log.debug("创建不存在的文件夹：" + tmpDir);
                return null;
            }
        }
        
        
        // 文件保存路径：以日期为文件夹
        String savePath = df.format(new Date());
        // 判断upload目录是否存在
        File filepath = new File(realpath + File.separator + savePath);
        if (!filepath.exists() || !filepath.isDirectory())
        {
            if (!filepath.mkdirs())
            {
                log.debug("创建不存在的文件夹：" + realpath + File.separator + savePath);
                return null;
            }
            
        }
        
        
        if (ServletFileUpload.isMultipartContent(request))
        {
            // 创建该对象
            DiskFileItemFactory dff = new DiskFileItemFactory();
            // 指定上传文件的临时目录
            dff.setRepository(tmpPath_file);
            // 指定在内存中缓存数据大小,单位为byte
            dff.setSizeThreshold(Constants.TMP_FILE_SIZE);
            // 创建该对象
            ServletFileUpload sfu = new ServletFileUpload(dff);
            // 指定单个上传文件的最大值
            sfu.setSizeMax(Constants.FILE_MAX_SIZE);
            
            FileItemIterator fii;
            BufferedInputStream in = null;
            BufferedOutputStream out = null;
            try
            {
                fii = sfu.getItemIterator(request);
                // 解析request
                // 请求,并返回FileItemIterator集合
                while (fii.hasNext())
                {
                    // 从集合中获得一个文件流
                    FileItemStream fis = fii.next();
                    // 过滤掉表单中非文件域
                    if (!fis.isFormField() && fis.getName().length() > 0)
                    {
                        // 保存的文件名为UUID
                        String uuid = imageUuid;
                        if (null == uuid || "".equals(uuid))
                        {
                            uuid = UUIDGenerator.getUUID();
                        }
                        String strFileName = fis.getName();
                        String strExt = strFileName.substring(strFileName.lastIndexOf("."));
                        String fileName = uuid + strExt.toLowerCase();
                        
                        String smallFileName = uuid+"_small" + strExt.toLowerCase();
                        
                        // 获得文件输入流
                        in = new BufferedInputStream(fis.openStream());
                        // 获得文件输出流
                        out = new BufferedOutputStream(new FileOutputStream(new File(filepath + File.separator + fileName)));
                        // 开始把文件写到你指定的上传文件夹
                        Streams.copy(in, out, true);
                        
                        
                        
                        //文件的相对路径
                        strArr[0] = savePath + "/" + fileName;
                        
                        //上传前文件的名称
                        strArr[1] = strFileName;
                        
                        
                        if(request.getParameter("compress")!=null&&request.getParameter("compress").equals("true")){
                        	DwindlePic mypic = new DwindlePic();
	                        if(request.getParameter("width")!=null&&request.getParameter("height")!=null){
	                        	int  width = new Integer(request.getParameter("width")).intValue();
		                        int height = new Integer(request.getParameter("height")).intValue();
		                        
		                        mypic.s_pic(filepath.toString()+ File.separator ,filepath.toString()+ File.separator ,fileName, smallFileName, width, height, true);
	                        	
	                        }else{
	                        	mypic.s_pic(filepath.toString()+ File.separator ,filepath.toString()+ File.separator ,fileName, smallFileName);
	                        }
	                        strArr[2] = savePath + "/" + smallFileName;
		                        
	                        //对照片压缩图片
	                        //boolean zipflag = zipImageFile(filepath + File.separator + fileName,filepath + File.separator + smallFileName,width, height);
	                        
	                        //if(zipflag==true){
	                        	//strArr[2] = savePath + "/" + smallFileName;
	                        //}else{
	                        	//strArr[2] = savePath + "/" + fileName;
		                    //}
                        }else{
                        	strArr[2] = "";
                        }
                        in.close();
                        out.close();
                    }
                }
            }
            catch (FileUploadException e)
            {
                log.error("文件上传失败 FileUploadException:", e);
            }
            catch (IOException e)
            {
                log.error("文件上传IOException:", e);
            }
            finally
            {
                if (null != in)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException e)
                    {
                        log.error("文件上传IOException:", e);
                    }
                }
                if (null != out)
                {
                    try
                    {
                        out.close();
                    }
                    catch (IOException e)
                    {
                        log.error("文件上传IOException:", e);
                    }
                }
            }
        }
        return strArr;
    }
    
    
    
    /**
     * 保存由副文本编辑器上传的文章中的图片
     * 
     * @throws IOException
     * @throws FileUploadException
     */
    public String[] saveImageOfArticle(HttpServletRequest request)
    {
        return saveImageOfArticle(request, "");
    }
    
    /**
     * 保存由副文本编辑器上传的文章中的图片
     * 
     * @param strUUID 文档上传的默认文件名 UUID
     * @throws IOException
     * @throws FileUploadException
     */
    public String[] saveImageOfArticle(HttpServletRequest request,String imageUuid)
    {
    	String[] strArr = new String[2];
        String realpath = Constants.ARTICLEIMAGE_UPLOAD_PATH;
        
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        
        String tmpDir = realpath + File.separator + "temp" + File.separator+ df.format(new Date()) + File.separator; // 临时目录
        // 判断临时目录是否存在
        File tmpPath_file = new File(tmpDir);
        if (!tmpPath_file.exists() || !tmpPath_file.isDirectory())
        {
            if (!tmpPath_file.mkdirs())
            {
                log.debug("创建不存在的文件夹：" + tmpDir);
                return null;
            }
        }
        
        
        // 文件保存路径：以日期为文件夹
        String savePath = df.format(new Date());
        // 判断upload目录是否存在
        File filepath = new File(realpath + File.separator + savePath);
        if (!filepath.exists() || !filepath.isDirectory())
        {
            if (!filepath.mkdirs())
            {
                log.debug("创建不存在的文件夹：" + realpath + File.separator + savePath);
                return null;
            }
            
        }
        
        
        if (ServletFileUpload.isMultipartContent(request))
        {
            // 创建该对象
            DiskFileItemFactory dff = new DiskFileItemFactory();
            // 指定上传文件的临时目录
            dff.setRepository(tmpPath_file);
            // 指定在内存中缓存数据大小,单位为byte
            dff.setSizeThreshold(Constants.TMP_FILE_SIZE);
            // 创建该对象
            ServletFileUpload sfu = new ServletFileUpload(dff);
            // 指定单个上传文件的最大值
            sfu.setSizeMax(Constants.FILE_MAX_SIZE);
            
            FileItemIterator fii;
            BufferedInputStream in = null;
            BufferedOutputStream out = null;
            try
            {
                fii = sfu.getItemIterator(request);
                // 解析request
                // 请求,并返回FileItemIterator集合
                while (fii.hasNext())
                {
                    // 从集合中获得一个文件流
                    FileItemStream fis = fii.next();
                    // 过滤掉表单中非文件域
                    if (!fis.isFormField() && fis.getName().length() > 0)
                    {
                        // 保存的文件名为UUID
                        String uuid = imageUuid;
                        if (null == uuid || "".equals(uuid))
                        {
                            uuid = UUIDGenerator.getUUID();
                        }
                        String strFileName = fis.getName();
                        String strExt = strFileName.substring(strFileName.lastIndexOf("."));
                        String fileName = uuid + strExt.toLowerCase();
                        // 获得文件输入流
                        in = new BufferedInputStream(fis.openStream());
                        // 获得文件输出流
                        out = new BufferedOutputStream(new FileOutputStream(new File(filepath + File.separator + fileName)));
                        // 开始把文件写到你指定的上传文件夹
                        Streams.copy(in, out, true);
                        
                        
                        
                        //文件的相对路径
                        strArr[0] = savePath + "/" + fileName;
                        
                        //上传前文件的名称
                        strArr[1] = strFileName;
                        
                        in.close();
                        out.close();
                    }
                }
            }catch (FileUploadException e)
            {
                log.error("文件上传失败 FileUploadException:", e);
            }
            catch (IOException e)
            {
                log.error("文件上传IOException:", e);
            }
            finally
            {
                if (null != in)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException e)
                    {
                        log.error("文件上传IOException:", e);
                    }
                }
                if (null != out)
                {
                    try
                    {
                        out.close();
                    }
                    catch (IOException e)
                    {
                        log.error("文件上传IOException:", e);
                    }
                }
            }
        }
        return strArr;
    }
    
    
    
    
    /**  
     * 压缩图片文件<br>  
     * 先保存原文件，再压缩、上传  
     *   
     * @param oldFilePath  
     *            要进行压缩的文件全路径  
     * @param width  
     *            宽度  
     * @param height  
     *            高度  
     * @return 返回压缩是否成功
     */  
    public static boolean zipImageFile(String oldFilePath,String newFilePath,int width, int height) {   
        if (oldFilePath == null) {
            return false;
        }
        try {
            /** 对服务器上的临时文件进行处理 */
            Image srcFile = ImageIO.read(new File(oldFilePath));
            int w = srcFile.getWidth(null);
            //System.out.println(w);
            int h = srcFile.getHeight(null);
            //System.out.println(h);
            //width = w/4;
            //height = h/4;
            
            //如果原图比要求的图片还小，则不需要进行压缩
            if(width>=w&&height>=h){
            	return false;
            }
            
            /** 宽,高设定 */
            BufferedImage tag = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);   
            tag.getGraphics().drawImage(srcFile, 0, 0, width, height, null);   
            
            
            /** 压缩之后存放位置 */  
            FileOutputStream out = new FileOutputStream(newFilePath);   
  
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);   
            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
            
            /** 压缩质量 */  
            jep.setQuality(1f, true);   
            encoder.encode(tag, jep);   
            out.close();
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
}
